#include "app_mqtt.h"
#include "thirdparty/log.c/log.h"
#include <MQTTClient.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

static MQTTClient client;
static MQTTClient_deliveryToken dt;
static MQTTClient_connectOptions options = MQTTClient_connectOptions_initializer;
static int (*message_arrive_callback)(char *);

void app_mqtt_connectionLostCallback(void *context, char *cause)
{
    assert(context == NULL);
    log_error("MQTTClient connection lost because of %s, exiting...", cause);
    exit(EXIT_FAILURE);
}

int app_mqtt_messageArrivedCallback(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    assert(context == NULL);
    char *msg = message->payload;
    log_debug("Message from topic %s arrived, content %s", topicName, msg);
    if (message_arrive_callback(msg) == 0)
    {
        MQTTClient_freeMessage(&message);
        MQTTClient_free(topicName);
        return 1;
    }
    else
    {
        return 0;
    }
}

void app_mqtt_deliveryCompleteCallback(void *context, MQTTClient_deliveryToken dt)
{
    assert(context == NULL);
    log_debug("Message with token %d delivered", dt);
}

int app_mqtt_init()
{
    log_debug("MQTTClient initializing...");
    // 创建客户端
    if (MQTTClient_create(&client, SERVER_URL, "atguigu-gateway", MQTTCLIENT_PERSISTENCE_NONE, NULL) != MQTTCLIENT_SUCCESS)
    {
        goto FAIL;
    }
    log_debug("MQTTClient create success");

    // 设置回调函数
    if (MQTTClient_setCallbacks(client, NULL,
                                app_mqtt_connectionLostCallback,
                                app_mqtt_messageArrivedCallback,
                                app_mqtt_deliveryCompleteCallback) != MQTTCLIENT_SUCCESS)
    {
        goto DESTROY_FAIL;
    }
    log_debug("MQTTClient set callback success");
    // 连接服务器

    // 配置用户名和秘密
    // options.username = "";
    // options.password = "";
    options.connectTimeout = 10000;
    options.keepAliveInterval = 20;
    options.cleansession = 1;

    if (MQTTClient_connect(client, &options) != MQTTCLIENT_SUCCESS)
    {
        goto DESTROY_FAIL;
    }
    log_debug("MQTTClient connect success");

    // 如果有需要，订阅相关话题
    if (MQTTClient_subscribe(client, PULL_TOPIC, 0) != MQTTCLIENT_SUCCESS)
    {
        goto DISCONNECT_FAIL;
    }
    log_debug("MQTTClient subscribe success");
    return 0;

DISCONNECT_FAIL:
    MQTTClient_disconnect(client, 0);
DESTROY_FAIL:
    log_warn("Init fail, destroying client");
    MQTTClient_destroy(&client);
FAIL:
    return -1;
}

int app_mqtt_send(char *json_str)
{
    // 发布消息
    if (MQTTClient_publish(client, PUSH_TOPIC, strlen(json_str) + 1, json_str, 1, 0, &dt) == MQTTCLIENT_SUCCESS)
    {
        log_debug("Message %s sended with token %d", json_str, dt);
        return 0;
    }
    log_warn("Message %s sended fail", json_str);
    return -1;
}

void app_mqtt_registerRecvCallback(int (*callback)(char *))
{
    message_arrive_callback = callback;
}

void app_mqtt_close()
{
    // 断开连接
    MQTTClient_disconnect(client, 0);
    // 销毁客户端
    MQTTClient_destroy(&client);
}
